﻿// Decompiled with JetBrains decompiler
// Type: Netick.NetickTransport
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using System.Collections.Generic;

#nullable disable
namespace Netick;

public class NetickTransport : NetworkTransport
{
  private CustomizableSocketTransport _transport;
  private Dictionary<Connection, NetickTransportConnection> _clients;
  private Queue<NetickTransportConnection> _freeClients;

  public override void Init()
  {
    this._clients = new Dictionary<Connection, NetickTransportConnection>(32 /*0x20*/);
    this._freeClients = new Queue<NetickTransportConnection>(32 /*0x20*/);
    this._transport = new CustomizableSocketTransport((INetickSocket) new NativeUDPSocket(), this.Engine.MaxClients);
    this._transport.OnConnectRequestEvent += new OnConnectionRequest(this.OnConnectRequest);
    this._transport.OnConnectFailedEvent += new Netick.OnConnectFailed(this.OnConnectFailed);
    this._transport.PeerConnectedEvent += new OnPeerConnected(this.OnConnected);
    this._transport.PeerDisconnectedEvent += new OnPeerDisconnected(this.OnDisconnected);
    this._transport.NetworkReceiveEvent += new OnNetworkReceive(this.OnReceive);
    int num = this.Engine.IsServer ? this.Engine.MaxClients : 4;
    for (int index = 0; index < num; ++index)
      this._freeClients.Enqueue(new NetickTransportConnection());
  }

  public override void Run(RunMode mode, int port)
  {
    NetickConfigData config = this.Engine._config;
    if (mode == RunMode.Client)
      this._transport.StartClient(16384 /*0x4000*/, 32768 /*0x8000*/);
    else
      this._transport.StartServer(port, 16384 /*0x4000*/ * this.Engine.MaxClients, 32768 /*0x8000*/ * this.Engine.MaxPlayers);
    this._transport.Timeout = 5.0;
  }

  public override void Shutdown() => this._transport.Stop();

  public override void PollEvents() => this._transport.Update();

  public override void Connect(
    string address,
    int port,
    byte[] connectionData,
    int connectionDataLength)
  {
    this._transport.Connect(address, port, connectionData, connectionDataLength);
  }

  public override void Disconnect(TransportConnection connection)
  {
    this._transport.Kick(((NetickTransportConnection) connection).Peer);
  }

  /// -------------------------------
  public void OnConnectRequest(NetworkConnectionRequest request)
  {
    if (this.NetworkPeer.OnConnectRequest(request.Data, request.DataLength, request.Source))
      request.Accept();
    else
      request.Refuse();
  }

  public void OnConnectFailed(IEndPoint address, ConnectionFailedReason reason)
  {
    this.Engine._gameEngine.OnConnectFailed(reason);
  }

  private void OnConnected(Connection peer)
  {
    NetickTransportConnection peer1 = this._freeClients.Dequeue();
    peer1.Peer = peer;
    this._clients.Add(peer, peer1);
    this.NetworkPeer.OnConnected((TransportConnection) peer1);
  }

  private void OnDisconnected(
    Connection peer,
    TransportDisconnectReason transportDisconnectReason)
  {
    if (peer == null || !this._clients.ContainsKey(peer))
      return;
    this.NetworkPeer.OnDisconnected((TransportConnection) this._clients[peer], transportDisconnectReason);
    this._freeClients.Enqueue(this._clients[peer]);
    this._clients.Remove(peer);
  }

  public void OnReceive(Connection peer, BitBuffer reader)
  {
    NetickTransportConnection connection;
    if (!this._clients.TryGetValue(peer, out connection))
      return;
    this.NetworkPeer.Receive((TransportConnection) connection, reader);
  }
}
